package com.mrogrape.notepad.io;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;

import com.mrogrape.util.StringUtils;



public class TextIO {
	
	/**
	 * 从文件读取文本。
	 * 
	 * @param file 文件
	 * @param charset 编码格式，为空则使用系统默认值。
	 * @param off 开始读取的位置，以字符记，不可为负。
	 * @param len 读取的字符个数，全部读取则设定为Integer.MAX_VALUE。
	 * @return 读取的文本
	 * @throws FileNotFoundException 如果文件未被找到
	 * @throws IOException 读取过程中发生IO异常
	 */
	public static String read(File file, String charset, long off, int len) throws FileNotFoundException, IOException{

		return TextIO.read(new FileInputStream(file), charset, off, len);
	}


	/**
	 * 从输入流读取文本,并关闭输入流。
	 * 
	 * <p>
	 * 注意，无论此方法是否被成功执行，输入流都将被关闭。
	 * 
	 * @param is 输入流
	 * @param charset 编码格式，为空则使用系统默认值。
	 * @param off 开始读取的位置，以字符记，不可为负。
	 * @param len 读取的字符个数，全部读取则设定为Integer.MAX_VALUE。
	 * @return 读取的文本
	 * @throws IOException 读取过程中发生IO异常
	 */
	public static String read(InputStream is, String charset, long off, int len) throws IOException{

		// 如果开始读取的位置小于0
		if(off < 0){

			throw new IllegalArgumentException("Offset cannot be less than 0");
		}

		// 如果len小于0
		if(len < 0){

			throw new IllegalArgumentException("Len cannot be less than 0");
		}

		BufferedReader reader = null;
		try{

			// 如果用户设定的字符集为空
			if(StringUtils.isEmpty(charset)){
				reader = new BufferedReader(new InputStreamReader(is), 1024);
			}
			else{
				reader = new BufferedReader(new InputStreamReader(is, charset), 1024);
			}

			// 确定开始点
			long unskip = off;
			do{
				unskip = unskip - reader.skip(unskip);
			}while(unskip > 0);

			// 读取
			StringBuilder sb = new StringBuilder();

			int read = 0;
			int count = 0;
			char[] buf = new char[1024];
			while((read = reader.read(buf,0,((len - count)>buf.length?buf.length:len-count)))!=-1){

				sb.append(buf,0,read);
				count += read;
				if(count >= len){
					break;
				}
			}

			return sb.toString();
		}finally{

			if(is != null){
				is.close();
			}

			if(reader != null){
				reader.close();
			}
		}
	}

	/**
	 * 
	 * @param text
	 * @param file
	 * @throws FileNotFoundException
	 * @throws IOException
	 */
	public static void write(String text, File file) throws FileNotFoundException, IOException{

		TextIO.write(text, file, null);
	}

	/**
	 * 
	 * @param text 
	 * @param file
	 * @param charset
	 * @throws IOException 
	 * @throws FileNotFoundException 
	 * @throws UnsupportedEncodingException
	 */
	public static void write(String text, File file, String charset) throws FileNotFoundException, UnsupportedEncodingException, IOException{

		TextIO.write(text,new FileOutputStream(file),charset);
	}

	/**
	 * 将文本写入到输出流。
	 * 
	 * @param text 文本内容
	 * @param out 输出流
	 * @param charset 输出时使用的文本编码
	 * @throws IOException 如果发生IOException
	 * @throws UnsupportedEncodingException 如果编码不被支持
	 */
	public static void write(String text, OutputStream out, String charset) throws UnsupportedEncodingException, IOException{

		BufferedWriter bw = null;
		try{

			if(StringUtils.isEmpty(charset)){
				bw = new BufferedWriter(new OutputStreamWriter(out));
			}
			else{
				bw = new BufferedWriter(new OutputStreamWriter(out, charset));
			}

			bw.write(text);
		}
		finally{

			if(bw != null){
				bw.close();
			}
		}
	}

}
